package com.zhihesj.anan.system.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiGettokenRequest;
import com.dingtalk.api.request.OapiUserGetRequest;
import com.dingtalk.api.request.OapiUserGetuserinfoRequest;
import com.dingtalk.api.response.OapiGettokenResponse;
import com.dingtalk.api.response.OapiUserGetResponse;
import com.dingtalk.api.response.OapiUserGetuserinfoResponse;
import com.taobao.api.ApiException;
import com.zhihesj.anan.base.entity.Dingtalk;
import com.zhihesj.anan.base.entity.Gitee;
import com.zhihesj.anan.base.entity.Github;
import com.zhihesj.anan.base.impl.BaseController;
import com.zhihesj.anan.message.Message;
import com.zhihesj.anan.message.MessageCodeEnum;
import com.zhihesj.anan.security.JwtTokenUtil;
import com.zhihesj.anan.system.entity.*;
import com.zhihesj.anan.system.service.*;
import com.zhihesj.anan.system.vo.UserSelectVo;
import com.zhihesj.anan.system.vo.UsersVo;
import net.sf.json.JSONArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.zhihesj.anan.utils.HttpClientUtil.*;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author anan
 * @since 2020-04-20
 */
@RestController
@RequestMapping("/system/user")
public class UserController extends BaseController {

    @Autowired
    private UsersService usersService;

    @Autowired
    private UserAuthsService userAuthsService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private UserDeptService userDeptService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private Github github;

    @Autowired
    private Gitee gitee;

    @Autowired
    private Dingtalk dingtalk;

    private final static String USER_ID = "userId";

    /**
     * 获取全部用户
     * @param userSelectVo 前端发来参数
     * @return
     */
    @GetMapping("/getUserList")
    public Message getUserList(UserSelectVo userSelectVo) {
        Map<String, Object> stringObjectMap = BeanUtil.beanToMap(userSelectVo, false, true);
        List<UsersVo> usersVos;
        if (stringObjectMap.size()==0 || stringObjectMap.isEmpty()){
            usersVos = usersService.selectPage(null);
        } else {
            usersVos= usersService.selectPage(stringObjectMap);
        }
        return Message.success(usersVos);
    }

    /**
     * 获取用户信息
     * @return
     */
    @GetMapping("/info")
    public Message info() {
        SecurityContext ctx = SecurityContextHolder.getContext();
        Authentication auth = ctx.getAuthentication();
        UserAuths users = (UserAuths) auth.getPrincipal();
        Map<String, Object> map = userAuthsService.getRolesByIdentifier(users.getIdentifier());
        map.put("roles",Convert.toList(map.get("roles")));
        return Message.success(map);
    }

    /**
     * 根据code以及登陆方式，获取token以及user信息，并返回前端
     * @param code
     * @return
     */
    @GetMapping("/githubauth")
    public Message githubauth(@RequestParam String code, @RequestParam String state) throws ApiException {
        String token = "";
        String auth = "";
        String responseStr = "";
        String str = "";
        Map<String, String> map = new HashMap<>(16);
        Users users = null;
        JSONObject jsonObject = null;
        if (state.equals(github.getState())) {
            auth = "github";
            map.put("client_id", github.getClientId());
            map.put("client_secret", github.getClientSecret());
            map.put("redirect_uri", github.getRedirectUri());
            map.put("code", code);
            map.put("state", github.getState());
            responseStr = doGet(github.getTokenUri(), map);
            Map<String, String> map1 = stringToMap(responseStr);
            token = map1.get("access_token");
            str = doGet(github.getUserUri(), map1);
        } else if (state.equals(gitee.getState())) {
            auth = "gitee";
            map.put("client_id", gitee.getClientId());
            map.put("client_secret",gitee.getClientSecret());
            map.put("redirect_uri", gitee.getRedirectUri());
            map.put("code", code);
            map.put("state", gitee.getState());
            map.put("grant_type", "authorization_code");
            responseStr = doPost(gitee.getTokenUri(), map);
            jsonObject = JSONObject.parseObject(responseStr);
            Map<String, String> map1 = new HashMap<>(16);
            token = jsonObject.getString("access_token");
            map1.put("access_token", token);
            str = doGet(gitee.getUserUri(), map1);
        } else if (state.equals(dingtalk.getState())){
            auth="dingtalk";
            //  获取token
            DefaultDingTalkClient client = new DefaultDingTalkClient(dingtalk.getTokenUri());
            OapiGettokenRequest request = new OapiGettokenRequest();
            request.setAppkey(dingtalk.getAppKey());
            request.setAppsecret(dingtalk.getAppSecret());
            request.setHttpMethod("GET");
            OapiGettokenResponse response= client.execute(request);

            // 获取UserId
            DingTalkClient client1 = new DefaultDingTalkClient(dingtalk.getUserUri());
            OapiUserGetuserinfoRequest request1 = new OapiUserGetuserinfoRequest();
            request1.setCode(code);
            request1.setHttpMethod("GET");
            OapiUserGetuserinfoResponse response1 = client1.execute(request1, response.getAccessToken());

            // 根据UserId获取用户信息
            DingTalkClient client2 = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/get");
            OapiUserGetRequest request2 = new OapiUserGetRequest();
            request2.setUserid(response1.getUserid());
            request2.setHttpMethod("GET");
            OapiUserGetResponse response2 = client2.execute(request2, response.getAccessToken());
            str=response2.getBody().toString();
        } else {
            return Message.error(MessageCodeEnum.STATE_ERROR);
        }
        jsonObject = JSONObject.parseObject(str);
        if (jsonObject == null) {
            return Message.error(MessageCodeEnum.API_ERROR);
        }
        if ("dingtalk".equals(auth)) {
            String mobile=jsonObject.getString("mobile");
            QueryWrapper wrapper=new QueryWrapper();
            wrapper.eq("nick_name",mobile);
            users = usersService.getOne(wrapper);
        }else {
            users = usersService.getById(jsonObject.getInteger("id"));
        }
        if (users == null) {
            QueryWrapper wrapper=new QueryWrapper();
            wrapper.eq("is_default",1);
            Role role= roleService.getOne(wrapper);
            if (!state.equals(dingtalk.getState())) {
                // 保存用户表
                Users users1 = new Users();
                users1.setId(jsonObject.getLong("id"));
                users1.setNickName(jsonObject.getString("login"));
                users1.setAvatar(jsonObject.getString("avatar_url"));
                usersService.save(users1);
                // 保存第三方用户表
                UserAuths userAuths = new UserAuths();
                userAuths.setUserId(jsonObject.getLong("id"));
                userAuths.setIdentifier(jsonObject.getString("login"));
                userAuths.setIdentityType(auth);
                userAuths.setCredential(token);
                userAuthsService.save(userAuths);
                // 保存默认权限表
                UserRole userRole = new UserRole();
                userRole.setUserId(userAuths.getUserId());
                userRole.setRoleId(role.getRoleId());
                userRoleService.save(userRole);
            } else {
                // 保存用户表
                Users users1 = new Users();
                users1.setId(jsonObject.getLong("mobile"));
                users1.setNickName(jsonObject.getString("mobile"));
                users1.setAvatar(jsonObject.getString("avatar"));
                usersService.save(users1);
                // 保存第三方用户表
                UserAuths userAuths = new UserAuths();
                userAuths.setUserId(users1.getId());
                userAuths.setIdentifier(jsonObject.getString("mobile"));
                userAuths.setIdentityType(auth);
                userAuths.setMobil(jsonObject.getString("mobile"));
                userAuths.setCredential(jsonObject.getString("openId"));
                userAuthsService.save(userAuths);
                // 保存默认权限表
                UserRole userRole = new UserRole();
                userRole.setUserId(userAuths.getUserId());
                userRole.setRoleId(role.getRoleId());
                userRoleService.save(userRole);
            }
            token = jwtTokenUtil.generateToken(state.equals("dingtalk") ? jsonObject.getString("mobile") :jsonObject.getString("login"));
        }else {
            token=jwtTokenUtil.generateToken(users.getNickName());
        }
        return Message.token(token);
    }

    /**
     * 根据部门id获取用户信息
     * @param deptIds
     * @return
     */
    @GetMapping("/getUserByDeptIds")
    public Message getUserByDeptIds(String deptIds) {
        String[] arr=deptIds.split(",");
        List<UsersVo> list =usersService.getUserByDeptIds(arr);
        return Message.success(list);
    }

    /**
     * String转MAP
     * @param params
     * @return
     */
    protected Map<String, String> stringToMap(String params) {
        String aa = params.substring(params.lastIndexOf("?") + 1, params.length());
        String[] bb = aa.split("&");
        String cc = null;
        String[] dd = null;
        String key = null;
        String value = null;
        Map<String, String> map = new HashMap<String, String>(16);
        for (String s : bb) {
            String[] s1 = s.split("=");
            JSONArray js = JSONArray.fromObject(s1);
            if (js.size() > 1) {
                key = (String) js.get(0);
                value = (String) js.get(1);
                map.put(key, value);
            }
        }
        return map;
    }

    @PostMapping("/updateUserByUserId")
    @Transactional
    public Message updateUserByUserId(@RequestBody Map<String,String> map) {
        System.out.println(map);
        long userId = Convert.toLong(map.get(USER_ID));
        if (userId==1) {
            return Message.success(MessageCodeEnum.USER_EDIT_ERROR);
        }
        // 修改用户
        UserAuths userAuths = Convert.convert(UserAuths.class, map);
        UpdateWrapper wrapper = new UpdateWrapper();
        wrapper.eq("user_id", userId);
        userAuthsService.update(userAuths, wrapper);

        // 更新部门
        QueryWrapper wrapper1 = new QueryWrapper();
        wrapper1.eq("user_id", userId);
        userDeptService.remove(wrapper1);
        UserDept userDept = new UserDept();
        userDept.setUserId(userId);
        userDept.setDeptId(Convert.toLong(map.get("deptId")));
        userDeptService.save(userDept);

        // 更新角色
        QueryWrapper wrapper2 = new QueryWrapper();
        wrapper2.eq("user_id", userId);
        userRoleService.remove(wrapper2);
        long[] roles = StrUtil.splitToLong(Convert.toStr(map.get("rolesIds")), ",");
        UserRole userRole = new UserRole();
        for (long role:roles) {
            userRole.setUserId(userId);
            userRole.setRoleId(role);
            userRoleService.save(userRole);
        }
        return Message.success(MessageCodeEnum.SUCCESS);
    }

    /**
     * 删除users userAuths
     * @param userAuths
     * @return
     */
    @DeleteMapping("/deleteUserById")
    public Message deleteUserById(@RequestBody UserAuths userAuths) {
        if (userAuths.getUserId() == 1) {
            return Message.success(MessageCodeEnum.USER_EDIT_ERROR);
        }
        QueryWrapper<Users> wrapper = new QueryWrapper<>();
        wrapper.eq("id", userAuths.getUserId());
        if (usersService.remove(wrapper)) {
            userAuthsService.removeById(userAuths);
        }
        return Message.success(MessageCodeEnum.DELETE_SUCCESS);
    }
}
